﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Practices.Unity;
using Sern.Abstracts.Tracker.DataContracts;
using Sern.Abstracts.Tracker.ServiceContracts;
using Sern.Common;
using Sern.ServiceImplementation;
using Sern.ServiceImplementation.TrackerDefinition.Data;
using NetServiceHost = System.ServiceModel.ServiceHost;
using ServiceTracker = Sern.ServiceImplementation.TrackerDefinition.Service.Tracker;


namespace Sern.ServiceHost.Tracker
{
    public static class TrackerHostFactory
    {

        

        /// <summary>
        /// In Azure for example, these addresses must be configurable by the run time environment. Hence you need the uri so that we get the port, hostname that the service is allowed to bind to.
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="trackerConnectionString"></param>
        /// <returns></returns>
        public static IDisposable CreateListener(TrackerConfiguration configuration)
        {
            var bindingScheme = ComponentLocator.Unity.Resolve<IBindingFactory>()[ClientType.Tracker]();
            var telemetryBindingScheme = ComponentLocator.Unity.Resolve<IBindingFactory>()[ClientType.TrackerTelemetry]();

            ComponentLocator.Unity.RegisterType<TrackerEntityContainer>(
                new EfObjectContextInjectionFactory<TrackerEntityContainer>(configuration.TrackerDbConnectionString));

            //This configuration can be overidden if the caller registers them on their own. It's a more advanced settings - hence whey it's left out of the regular TrackerConfiguration.
            

            NetServiceHost trackerHost = new NetServiceHost(
                new ServiceTracker(),
                bindingScheme.GetBaseUri(configuration.HostName));                        

            trackerHost.AddServiceEndpoint(
                typeof (ITracker),
                bindingScheme.Binding,
                bindingScheme.GetEndpointUri(configuration.HostName));


            var trackerEndPoint = trackerHost.AddServiceEndpoint(
                typeof (ITrackerTelemetryReceiver),
                telemetryBindingScheme.Binding,
                telemetryBindingScheme.GetEndpointUri(configuration.HostName))
                    .CreateMsmqIfNostExists();

            trackerHost.EnableMex();

            trackerHost.ConfigureAsSingleton();


            trackerHost.Open();

            return DynamicDisposable
                .CreateFrom(
                    () => { 
                        trackerHost.Close();
                        trackerEndPoint.DeleteMsmqIfExists();
                    }
                );
        }
    }
}
